package com.gonsin.i18n.logic.services;

import com.gonsin.i18n.logic.machine.Languages;
import com.gonsin.i18n.logic.models.KeywordModel;
import com.gonsin.i18n.logic.config.I18nConfig;
import com.google.gson.Gson;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.io.FileUtils;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * keyword翻译列表的容器
 * 
 * 该类最主要存放 一个 项目中用到的所有语言
 */
@Slf4j
public class KeywordContainer {

    private I18nConfig config;  // 配置文件

    // private Map<String, String> keywords; // 当前语言列表

    /**
     * key = lang 语言字符串
     * value = KeywordFile 翻译表
     */
    private Map<String, KeywordFile> keywords; // 当前语言列表

    private String projectName;  // 当前项目

    // private String lang;        // 当前语言

    private File langFolder;        // 当前项目的目录


    // /**
    //  * 创建新的语言项目的时候使用
    //  * @param config 配置内容
    //  * @param projectName
    //  * @param keywords
    //  */
    // @SneakyThrows
    // public KeywordContainer(I18nConfig config, String projectName, Map<String, String> keywords) {
    //     this.config = config;
    //     this.projectName = projectName;
    //     this.langFolder = new File(new File(config.getLangPath()).getAbsolutePath() + File.separator + projectName + File.separator);
    //     // this.title = title;
    //     if(!langFolder.exists()){
    //         File parent = langFolder.getParentFile();
    //         if(!parent.exists()){
    //             parent.mkdirs();
    //         }
    //         langFolder.mkdirs();
    //     }

    //     // TODO 直接主动读取 本地目录
    //     this.keywords = new HashMap<>();
    // }

    @SneakyThrows
    public KeywordContainer(I18nConfig config, File langFolder) {
        this.config = config;
        this.langFolder = langFolder;
        this.projectName = langFolder.getName();
        this.keywords = new ConcurrentHashMap<>();
        if(!langFolder.exists()){
            langFolder.mkdirs();
        }


        Collection<File> langFiles = FileUtils.listFiles(langFolder, new String[]{"json"}, false);
        for(File langFile : langFiles){
            String json = FileUtils.readFileToString(langFile,"UTF-8");
            if(StringUtils.isEmpty(json)){
                continue;
            }
//            KeywordFileModel model = new Gson().fromJson(json, KeywordFileModel.class);
            KeywordFileModel model = new Gson().fromJson(json, KeywordFileModel.class);
            if(!"gonsin".equals(model.getMarker())){
                continue;
            }
            String lang = model.getLang();
            // String title = keywordFile.getTitle();
            // Map<String, String> keywords = keywordFile.getMessages();

            keywords.put(lang, new KeywordFile(model));

            // if(!langFile.exists()){
            //     File parent = langFile.getParentFile();
            //     if(!parent.exists()){
            //         parent.mkdirs();
            //     }
            //     langFile.createNewFile();
            //     save();
            // }
        }
    }

    /**
     * 修改配置i18n的翻译
     */
    public synchronized void update(String lang, String origin, String after) {

        KeywordFile keywordFile = keywords.get(lang);
//        synchronized(this){
//            if(keywordFile == null){
//                keywordFile = new KeywordFile();
//                keywordFile.setLang(lang);
//                keywordFile.setProjectName(projectName);
//                keywordFile.setMarker("gonsin");
//                keywordFile.setTitle();
//                keywords.put(lang, keywordFile);
//            }
//        }
        if(keywordFile == null){
            return;
        }

        if(StringUtils.isEmpty(after)){
            keywordFile.remove(origin);
        } else {
            keywordFile.put(origin, after, null);
        }
    }

    /**
     * 添加i18n的翻译 （如果已存在则不做处理）
     */
    public synchronized void add(String lang, String origin, String after, boolean fromClient, String common) {

        KeywordFile keywordFile = keywords.get(lang);
        if(!fromClient){
            synchronized(this){
                if(keywordFile == null){
                    keywordFile = new KeywordFile();
                    keywordFile.setLang(lang);
                    Languages languages = Languages.get(lang);
                    keywordFile.setTitle(languages.getSelfTitle());
                    keywordFile.setProjectName(projectName);
                    keywords.put(lang, keywordFile);
                }
            }
        }
        if(keywordFile == null){
            return;
        }

        if(keywordFile.contains(origin)){
            return;
        }
        keywordFile.put(origin, after, common);
    }

//    /**
//     * 初始化一个lang容器，并且创建对应的文件
//     */
//    public static KeywordContainer initAndCreateFile(I18nConfig config, String title, String lang) {
//        File parent = new File(config.getLangPath());
//        if(!parent.exists()){
//            parent.mkdirs();
//        }
//        File child = new File(parent.getAbsolutePath() + File.separator + lang + ".json");
//        if(child.exists()){
//            throw new GonsinI18nException("语言【{}】已被创建，无法再次创建，请检查代码是否重复调用 initAndCreateFile ", lang);
//        }
//        try {
//            child.createNewFile();
//            FileUtils.writeStringToFile(child, "{}");
//        } catch (IOException e) {
//            throw new GonsinI18nException("创建语言【{}】文件失败。 ", lang);
//        }
//
//        KeywordContainer keywordContainer = new KeywordContainer(config, title, lang, new HashMap<>());
//        return keywordContainer;
//    }

    /**
     * 获取所有的键值对
     */
    public Map<String, String> all(String lang) {
        return new HashMap<>(keywords.get(lang).getMessages());
    }


    /**
     * 语言转换
     */
    public String transfer(String lang, String content, String common, Object[] args) {

        KeywordFile keywordFile = keywords.get(lang);
        if(keywordFile == null){
            return content;
        }

        String after = (String) keywordFile.getMessages().get(content);
        if(after == null){
            FormattingTuple ft = MessageFormatter.arrayFormat(content, args);
            String result = ft.getMessage();
            keywordFile.put(content, content, common);

            // 其他语言也要添加
            keywords.forEach((l, k) -> {
                if(k.getMessages().get(content) == null){
                    k.put(content, content, common);
                }
            });

            return result;
        }
        FormattingTuple ft = MessageFormatter.arrayFormat(after, args);
        return ft.getMessage();
    }


    /**
     * 添加语言
     * 包含步骤
     * 1、创建语言文件
     * 2、添加基础的内容
     * @param model
     */
    public void addLang(KeywordModel model) {
        // 以基础语言包复制一个语言文件

        File json = new File(langFolder.getAbsolutePath() + File.separator + model.getLang() + ".json");
        if(json.exists()){
            return;
        }

        I18nConfig config = I18nInstance.CONFIG;
        String defaultLang = config.getDefaultLang();

        KeywordFile defaultKeywordFile = keywords.get(defaultLang);
        KeywordFile newFile = new KeywordFile();
        if(defaultKeywordFile != null){
            // BeanUtils.copyProperties(defaultKeywordFile, newFile);
            Map<String, String> newMessages = new ConcurrentHashMap<>();
            newMessages.putAll(defaultKeywordFile.getMessages());
            newFile.setMessages(newMessages);
        }
        Languages languages = Languages.get(model.getLang());
        newFile.setTitle(languages.getTitle());
        newFile.setLang(languages.getLang());
        newFile.setProjectName(projectName);
        newFile.save();
        keywords.put(model.getLang(), newFile);
//        String jsonContent = new Gson().toJson(newFile);
//
//
//        try {
//            json.createNewFile();
//            FileUtils.writeStringToFile(json, jsonContent, config.getEncoder());
//            keywords.put(model.getLang(), newFile);
//        } catch (IOException e) {
//            log.error(e.toString(), e);
//            throw new GonsinI18nException("添加文件时报错");
//        }

        
    }

    /**
     * 删除语言
     */
    public void deleteLang(String lang) {
        File json = new File(langFolder.getAbsolutePath() + File.separator + lang + ".json");
        if(json.exists()){
            json.delete();
        }

        keywords.remove(lang);
    }


    /**
     * 获取该项目下所有语言
     * @return
     */
    public List<KeywordModel> allLangs() {
        return keywords.values().stream().map(k -> new KeywordModel(k.getTitle(), k.getLang())).collect(Collectors.toList());
    }


    /**
     * 复制一份语言包
     * 主要为了防止引用被修改
     * @param lang 语言
     * @return
     */
    public KeywordFile copyKeywordFile(String lang) {
        KeywordFile needCopy = keywords.get(lang);
        if(needCopy == null){
            return null;
        }
        KeywordFile newFile = new KeywordFile();
        Map<String, String> newMessages = new ConcurrentHashMap<>();
        newMessages.putAll(needCopy.getMessages());
        newFile.setMessages(newMessages);
        newFile.setLang(needCopy.getLang());
        newFile.setMarker(needCopy.getMarker());
        newFile.setTitle(needCopy.getTitle());
        newFile.setProjectName(needCopy.getProjectName());
        return newFile;
    }


    /**
     * 导入 新的语言包
     * @param model
     */
    public void putAll(KeywordFileModel model) {
        KeywordFile origin = keywords.get(model.getLang());
        if(origin == null){
            keywords.put(model.getLang(), new KeywordFile(model));
            return;
        }

        origin.getMessages().putAll(model.getMessages());
        origin.save();
    }


    /**
     * 为具体的语言导入新的语言包
     */
    public void putLang(String lang, KeywordFileModel keywordFileModel) {
        KeywordFile origin = keywords.get(lang);
        if(origin == null){
            keywords.put(lang, new KeywordFile(keywordFileModel));
            return;
        }

        origin.getMessages().putAll(keywordFileModel.getMessages());
        origin.save();
    }

    // /**
    //  * 查看是否包含某个字符串
    //  */
    // public boolean contains(String origin) {
    //     return keywords.containsKey(origin);
    // }
}
